import axios, { AxiosInstance } from 'axios';
import type { QcRequestConfig } from './type';
import { ElLoading, ElMessage } from 'element-plus';
import { ILoadingInstance } from 'element-plus/lib/el-loading/src/loading.type';

export default class QcRequest {
  instance: AxiosInstance;
  loading?: ILoadingInstance;
  isShowLoading?: boolean;

  constructor(config: QcRequestConfig) {
    const { interceptors } = config;

    const instance = axios.create(config);

    // todo 单个实列中的拦截器
    if (interceptors) {
      const {
        requestInterceptor,
        requestInterceptorCatch,
        responseInterceptor,
        responseInterceptorCatch,
      } = interceptors;

      instance.interceptors.request.use(
        requestInterceptor,
        requestInterceptorCatch
      );

      instance.interceptors.response.use(
        responseInterceptor,
        responseInterceptorCatch
      );
    }

    // todo 全局拦截器 执行顺序早于局部拦截器(后添加先执行)
    instance.interceptors.request.use(
      (config: QcRequestConfig) => {
        config.headers['token'] = 'myToken';
        const isShowLoading = config.showLoading ?? false;

        this.isShowLoading = isShowLoading;
        if (isShowLoading) {
          this.loading = ElLoading.service({
            lock: true,
            text: '正在请求',
            background: 'rgba(0,0,0,.5)',
          });
        }

        return config;
      },

      (err) => {
        return err;
      }
    );

    instance.interceptors.response.use(
      (response) => {
        this.loading?.close();

        return new Promise((resolve, reject) => {
          const { data } = response;

          const code = data.code;
          if (code && code < 0) {
            if (data.data) {
              ElMessage({
                message: data.data,
                type: 'error',
              });
            }
            reject(data);
          } else {
            resolve(data);
          }

          // if (data) {
          //   const { success } = data;
          //   if (success) {
          //     r(data);
          //   } else {
          //     console.log(data, '出错了, 自定义reject interceptors');

          //     j(data);
          //   }
          // } else {
          //   j(response);
          // }
        });
      },

      (err) => {
        this.loading?.close();
        return Promise.reject(err);
      }
    );

    this.instance = instance;
  }

  request<T = any>(config: QcRequestConfig<T>): Promise<T> {
    // 局部拦截
    const { interceptors } = config;

    if (interceptors && interceptors.requestInterceptor) {
      config = interceptors.requestInterceptor(config);
    }

    return new Promise((resolve, reject) => {
      this.instance.request<any, T>(config).then(
        (res) => {
          if (interceptors && interceptors.responseInterceptor) {
            res = interceptors.responseInterceptor(res);
          }

          resolve(res);
        },
        (err) => {
          reject(err);
        }
      );
    });
  }

  get<T>(config: QcRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' });
  }

  post<T>(config: QcRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'POST' });
  }

  delete<T>(config: QcRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'DELETE' });
  }

  patch<T>(config: QcRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'PATCH' });
  }

  put<T>(config: QcRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: 'PUT' });
  }
}
